home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / tutorial / t12 / cannon.cpp.z / cannon.cpp
C/C++ Source or Header  |  2002-04-08  |  4KB  |  200 lines

  1. /****************************************************************
  2. **
  3. ** Implementation CannonField class, Qt tutorial 12
  4. **
  5. ****************************************************************/
  6.  
  7. #include "cannon.h"
  8. #include <qtimer.h>
  9. #include <qpainter.h>
  10. #include <qpixmap.h>
  11. #include <qdatetime.h>
  12.  
  13. #include <math.h>
  14. #include <stdlib.h>
  15.  
  16.  
  17. CannonField::CannonField( QWidget *parent, const char *name )
  18.         : QWidget( parent, name )
  19. {
  20.     ang = 45;
  21.     f = 0;
  22.     timerCount = 0;
  23.     autoShootTimer = new QTimer( this, "movement handler" );
  24.     connect( autoShootTimer, SIGNAL(timeout()),
  25.          this, SLOT(moveShot()) );
  26.     shoot_ang = 0;
  27.     shoot_f = 0;
  28.     target = QPoint( 0, 0 );
  29.     setPalette( QPalette( QColor( 250, 250, 200) ) );
  30.     newTarget();
  31. }
  32.  
  33.  
  34. void CannonField::setAngle( int degrees )
  35. {
  36.     if ( degrees < 5 )
  37.     degrees = 5;
  38.     if ( degrees > 70 )
  39.     degrees = 70;
  40.     if ( ang == degrees )
  41.     return;
  42.     ang = degrees;
  43.     repaint( cannonRect(), FALSE );
  44.     emit angleChanged( ang );
  45. }
  46.  
  47.  
  48. void CannonField::setForce( int newton )
  49. {
  50.     if ( newton < 0 )
  51.     newton = 0;
  52.     if ( f == newton )
  53.     return;
  54.     f = newton;
  55.     emit forceChanged( f );
  56. }
  57.  
  58.  
  59. void CannonField::shoot()
  60. {
  61.     if ( autoShootTimer->isActive() )
  62.     return;
  63.     timerCount = 0;
  64.     shoot_ang = ang;
  65.     shoot_f = f;
  66.     autoShootTimer->start( 50 );
  67. }
  68.  
  69.  
  70. void  CannonField::newTarget()
  71. {
  72.     static bool first_time = TRUE;
  73.     if ( first_time ) {
  74.     first_time = FALSE;
  75.     QTime midnight( 0, 0, 0 );
  76.     srand( midnight.secsTo(QTime::currentTime()) );
  77.     }
  78.     QRegion r( targetRect() );
  79.     target = QPoint( 200 + rand() % 190,
  80.              10  + rand() % 255 );
  81.     repaint( r.unite( targetRect() ) );
  82. }
  83.  
  84.  
  85. void CannonField::moveShot()
  86. {
  87.     QRegion r( shotRect() );
  88.     timerCount++;
  89.  
  90.     QRect shotR = shotRect();
  91.  
  92.     if ( shotR.intersects( targetRect() ) ) {
  93.     autoShootTimer->stop();
  94.     emit hit();
  95.     } else if ( shotR.x() > width() || shotR.y() > height() ) {
  96.     autoShootTimer->stop();
  97.     emit missed();
  98.     } else {
  99.     r = r.unite( QRegion( shotR ) );
  100.     }
  101.  
  102.     repaint( r );
  103. }
  104.  
  105.  
  106. void CannonField::paintEvent( QPaintEvent *e )
  107. {
  108.     QRect updateR = e->rect();
  109.     QPainter p( this );
  110.  
  111.     if ( updateR.intersects( cannonRect() ) )
  112.     paintCannon( &p );
  113.     if ( autoShootTimer->isActive() &&
  114.      updateR.intersects( shotRect() ) )
  115.     paintShot( &p );
  116.     if ( updateR.intersects( targetRect() ) )
  117.     paintTarget( &p );
  118. }
  119.  
  120.  
  121. void CannonField::paintShot( QPainter *p )
  122. {
  123.     p->setBrush( black );
  124.     p->setPen( NoPen );
  125.     p->drawRect( shotRect() );
  126. }
  127.  
  128.  
  129. void CannonField::paintTarget( QPainter *p )
  130. {
  131.     p->setBrush( red );
  132.     p->setPen( black );
  133.     p->drawRect( targetRect() );
  134. }
  135.  
  136.  
  137. const QRect barrelRect(33, -4, 15, 8);
  138.  
  139. void CannonField::paintCannon( QPainter *p )
  140. {
  141.     QRect cr = cannonRect();
  142.     QPixmap pix( cr.size() );
  143.     pix.fill( this, cr.topLeft() );
  144.  
  145.     QPainter tmp( &pix );
  146.     tmp.setBrush( blue );
  147.     tmp.setPen( NoPen );
  148.  
  149.     tmp.translate( 0, pix.height() - 1 );
  150.     tmp.drawPie( QRect( -35,-35, 70, 70 ), 0, 90*16 );
  151.     tmp.rotate( -ang );
  152.     tmp.drawRect( barrelRect );
  153.     tmp.end();
  154.  
  155.     p->drawPixmap( cr.topLeft(), pix );
  156. }
  157.  
  158.  
  159. QRect CannonField::cannonRect() const
  160. {
  161.     QRect r( 0, 0, 50, 50 );
  162.     r.moveBottomLeft( rect().bottomLeft() );
  163.     return r;
  164. }
  165.  
  166.  
  167. QRect CannonField::shotRect() const
  168. {
  169.     const double gravity = 4;
  170.  
  171.     double time      = timerCount / 4.0;
  172.     double velocity  = shoot_f;
  173.     double radians   = shoot_ang*3.14159265/180;
  174.  
  175.     double velx      = velocity*cos( radians );
  176.     double vely      = velocity*sin( radians );
  177.     double x0        = ( barrelRect.right()  + 5 )*cos(radians);
  178.     double y0        = ( barrelRect.right()  + 5 )*sin(radians);
  179.     double x         = x0 + velx*time;
  180.     double y         = y0 + vely*time - 0.5*gravity*time*time;
  181.  
  182.     QRect r = QRect( 0, 0, 6, 6 );
  183.     r.moveCenter( QPoint( qRound(x), height() - 1 - qRound(y) ) );
  184.     return r;
  185. }
  186.  
  187.  
  188. QRect CannonField::targetRect() const
  189. {
  190.     QRect r( 0, 0, 20, 10 );
  191.     r.moveCenter( QPoint(target.x(),height() - 1 - target.y()) );
  192.     return r;
  193. }
  194.  
  195.  
  196. QSizePolicy CannonField::sizePolicy() const
  197. {
  198.     return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
  199. }
  200.